package com.hksj.am.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.hksj.am.mapper.AmmoniaCockpitMapper;
import com.hksj.am.query.AlarmDetailQuery;
import com.hksj.am.query.AmmoniaCockpitQuery;
import com.hksj.am.vo.AlarmDeviceInfoVO;
import com.hksj.am.vo.AlarmNumTrendVO;
import com.hksj.am.vo.AlarmRoomVO;
import com.hksj.am.vo.CurrentAlarmDeviceInfoVO;
import com.hksj.common.core.common.SpecialityModelCodeEnum;
import com.hksj.common.core.enums.DeviceState;
import com.hksj.common.core.util.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author fjt
 * @data 2024/11/5 18:12
 * @describe 氨气监测系统驾驶舱
 */
@Service
public class AmmoniaCockpitService {


    @Autowired
    private AmmoniaCockpitMapper ammoniaCockpitMapper;


    /**
     * 查询当前报警设备信息
     * @param query
     * @return
     */
    public CurrentAlarmDeviceInfoVO queryCurrentAlarmDevice(AmmoniaCockpitQuery query){
        CurrentAlarmDeviceInfoVO currentAlarmDeviceInfoVO = new CurrentAlarmDeviceInfoVO();
        query.setCode(SpecialityModelCodeEnum.ammonia_monitor.getCode());
        // 查询在线设备数量
        Integer onlineNum = ammoniaCockpitMapper.queryOnlineNum(query);
        currentAlarmDeviceInfoVO.setOnlineNum(ObjectUtil.isNotNull(onlineNum) ? onlineNum : 0);

        // 查询报警中的设备(在线)
        query.setState(DeviceState.online.getValue());
        List<String> deviceIdList = ammoniaCockpitMapper.queryCurrentAlarmDeviceId(query);
        if (CollUtil.isEmpty(deviceIdList)){
            currentAlarmDeviceInfoVO.setAlarmNum(0);
            return currentAlarmDeviceInfoVO;
        }

        currentAlarmDeviceInfoVO.setAlarmNum(deviceIdList.size());
        // 查询在指定的设备集合中，当前处于报警中的设备情况
        List<AlarmDeviceInfoVO> alarmDeviceInfoVOList = ammoniaCockpitMapper.queryAlarmDevice(deviceIdList);
        currentAlarmDeviceInfoVO.setAlarmDeviceInfoList(alarmDeviceInfoVOList);
        return currentAlarmDeviceInfoVO;
    }


    /**
     * 告警区域排行Top5（最近7天） 按房间统计
     * @param query
     * @return
     */
    public List<AlarmRoomVO> queryAlarmNum(AmmoniaCockpitQuery query){
        query.setCode(SpecialityModelCodeEnum.ammonia_monitor.getCode());
        query.setEndTime(DateUtil.convertToDate(LocalDateTime.now()));
        query.setStartTime(DateUtil.convertToDate(LocalDateTime.now().minusDays(7)));
        return ammoniaCockpitMapper.queryAlarmNum(query);
    }


    /**
     * 告警次数趋势（最近7天）
     * @param query
     * @return
     */
    public List<AlarmNumTrendVO> queryAlarmTrend(AmmoniaCockpitQuery query){
        query.setCode(SpecialityModelCodeEnum.ammonia_monitor.getCode());
        query.setEndTime(DateUtil.convertToDate(LocalDateTime.now()));
        query.setStartTime(DateUtil.convertToDate(LocalDateTime.now().minusDays(7)));
        List<AlarmNumTrendVO> list = ammoniaCockpitMapper.queryAlarmTrend(query);
        Map<LocalDate, Integer> map = new HashMap<>();
        if (CollUtil.isNotEmpty(list)){
            map = list.stream().collect(Collectors.toMap(p -> p.getCreateTime(), p -> p.getNum()));
        }

        // 获取指定时间段内的每一天
        List<LocalDate> dateList = DateUtil.getDatesInRange(DateUtil.convertToLocalDate(query.getStartTime()), DateUtil.convertToLocalDate(query.getEndTime()));
        List<AlarmNumTrendVO> voList = new ArrayList<>(dateList.size());
        Map<LocalDate, Integer> finalMap = map;
        dateList.forEach(localDate -> {
            int num = ObjectUtil.isNotNull(finalMap.get(localDate)) ? finalMap.get(localDate) : 0;
            AlarmNumTrendVO vo = AlarmNumTrendVO.builder().createTime(localDate).num(num).build();
            voList.add(vo);
        });
        // 按时间升序排序
        return voList.stream().sorted(Comparator.comparing(AlarmNumTrendVO::getCreateTime, Comparator.naturalOrder())).collect(Collectors.toList());
    }


    /**
     * 告警记录详情（最近7天）
     * @param query
     * @return
     */
    public List<AlarmDeviceInfoVO> queryAlarmDetail(AmmoniaCockpitQuery query){
        AlarmDetailQuery alarmDetailQuery = AlarmDetailQuery.builder()
                .code(SpecialityModelCodeEnum.ammonia_monitor.getCode())
                .paths(query.getPaths()).departmentItemValue(query.getDepartmentItemValue())
                .startTime(DateUtil.convertToDate(LocalDateTime.now().minusDays(7)))
                .endTime(DateUtil.convertToDate(LocalDateTime.now()))
                .build();
        return ammoniaCockpitMapper.queryAlarmDetail(alarmDetailQuery, null);
    }


}
